/**
 * Copyright 2008-2009 HAN.BIFANG
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package han.bifang.business.stat;

import han.bifang.business.bashe.BasheClient;
import han.bifang.business.dao.BusBindingDao;
import han.bifang.business.dao.StatBusDao;
import han.bifang.business.dao.StatDetailLogDao;
import han.bifang.business.dao.StatServiceDao;
import han.bifang.common.entity.EntityConstants;
import han.bifang.common.entity.SoaHttpBinding;
import han.bifang.common.entity.SoaLogDetail;
import han.bifang.common.entity.SoaLogErrorInfo;
import han.bifang.common.entity.SoaRetryRecord;
import han.bifang.common.entity.SoaStatBus;
import han.bifang.common.entity.SoaStatDetailLog;
import han.bifang.common.entity.SoaStatService;
import han.bifang.common.exception.BifangErrorCode;
import han.bifang.common.exception.BifangException;
import han.bifang.common.utils.CommonUtils;
import han.bifang.common.utils.RetryUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;

import v1.log.bifang.han.LogQueryRequestDocument;
import v1.log.bifang.han.LogQueryResponseDocument;
import v1.log.bifang.han.RetryRequestDocument;
import v1.log.bifang.han.RetryResponseDocument;
import v1.log.bifang.han.MessageExchangeDocument.MessageExchange;
import v1.log.bifang.han.MessageExchangeDocument.MessageExchange.ErrorInfo;
import v1.log.bifang.han.RetryRecordDocument.RetryRecord;
import v1.message.bashe.han.BasheMessageDocument;

/**
 * @Author kent
 */
public class StatManager {

	public static SoaStatBus getStatBus(String busCode) throws BifangException {
		try {
			return StatBusDao.getStatBus(busCode);
		} catch (BifangException e) {

			throw e;

		}
	}

	public static SoaStatService getStatService(String serCode, String version)
			throws BifangException {
		try {
			return StatServiceDao.getStatService(serCode, version);
		} catch (BifangException e) {

			throw e;

		}
	}

	public static SoaStatService getStatService(String serCode)
			throws BifangException {
		try {
			return StatServiceDao.getStatService(serCode);
		} catch (BifangException e) {

			throw e;

		}
	}

	public static ArrayList searchStatLog(SoaStatDetailLog log, Long beginDate,
			Long endDate, int page, int pageSize) throws BifangException {
		try {
			System.out.println(log.getBusCode());
			String hql = "from SoaStatDetailLog l where 1=1  ";
			if (!CommonUtils.isEmpty(log.getBusCode())) {
				hql += " and l.busCode = '" + log.getBusCode() + "'";
			}
			if (!CommonUtils.isEmpty(log.getRequestId())) {
				hql += " and l.requestId = '" + log.getRequestId() + "'";
			}
			if (!CommonUtils.isEmpty(log.getServiceCode())) {
				hql += " and l.serviceCode = '" + log.getServiceCode() + "'";
			}
			if (!CommonUtils.isEmpty(log.getVersion())) {
				hql += " and l.version = '" + log.getVersion() + "'";
			}
			if (!CommonUtils.isEmpty(log.getStatus())) {
				hql += " and l.status = '" + log.getStatus() + "'";
			}
			if (beginDate != null) {
				hql += " and l.callTime > " + beginDate;
			}
			if (endDate != null) {
				hql += " and l.callTime < " + endDate;
			}

			hql += " order by l.callTime desc";

			return StatDetailLogDao.searchStatLog(hql, page, pageSize);

		} catch (BifangException e) {

			throw e;

		}
	}

	public static SoaLogDetail getMessageExchange(String logId)
			throws BifangException {

		SoaStatDetailLog log = StatDetailLogDao.getStatLogByMessageLog(logId);
		SoaHttpBinding hb = (SoaHttpBinding) BusBindingDao.getBusBinding(log
				.getBusCode(), EntityConstants.BUS_BINDING_LOG_QUERY,
				EntityConstants.BINDING_HTTP);
		LogQueryRequestDocument doc = LogQueryRequestDocument.Factory
				.newInstance();
		doc.addNewLogQueryRequest();
		doc.getLogQueryRequest().addNewViewMessageExchangeRequest()
				.setMessageId(logId);

		LogQueryResponseDocument resDoc = BasheClient.query(doc, hb.getUrl(),
				60);
		MessageExchange me = resDoc.getLogQueryResponse()
				.getViewMessageExchangeResponse().getMessageExchangeArray(0);

		SoaLogDetail d = new SoaLogDetail();
		d.setId(me.getId());
		BasheMessageDocument req = BasheMessageDocument.Factory.newInstance();
		req.setBasheMessage(me.getRequest().getBasheMessage());
		d.setRequest(req.toString());
		if (me.getResponse() != null) {
			BasheMessageDocument res = BasheMessageDocument.Factory
					.newInstance();
			res.setBasheMessage(me.getResponse().getBasheMessage());
			d.setResponse(res.toString());
		}
		HashMap<String, ErrorInfo> etmp = new HashMap<String, ErrorInfo>();
		if (me.getErrorInfoList().size() > 0) {
			for (ErrorInfo e : me.getErrorInfoList()) {
				etmp.put(e.getErrorMsgId(), e);
			}
		}
		if (me.getRetryRecordList().size() > 0) {
			ArrayList<SoaRetryRecord> res = new ArrayList<SoaRetryRecord>();
			for (RetryRecord r : me.getRetryRecordList()) {
				SoaRetryRecord sr = new SoaRetryRecord();
				sr.setId(r.getId());
				sr.setRetryTime(CommonUtils.formatDate(new Date(Long
						.parseLong(r.getRetryTime()))));
				if (r.getRetryData() != null) {
					try {
						XmlObject x = RetryUtils.getRetryData(r.getRetryData());
						String ss = x.toString().replace("<", "&lt;");
						sr.setRetryData(ss);
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
				if (r.getErrorMsgId() != null) {
					ErrorInfo e = etmp.get(r.getErrorMsgId());
					sr.setErrorTrace(e.getBasheError().getErrorCode() + " "
							+ e.getBasheError().getErrorMsg() + " "
							+ e.getBasheError().getErrorTrace());
					etmp.remove(r.getErrorMsgId());
				}
				sr.setStatus(r.getStatus());

				res.add(sr);
			}
			d.setRetryRecord(res);
		}
		ArrayList<SoaLogErrorInfo> errs = new ArrayList<SoaLogErrorInfo>();
		Iterator<ErrorInfo> it = etmp.values().iterator();
		while (it.hasNext()) {
			ErrorInfo ee = it.next();
			SoaLogErrorInfo se = new SoaLogErrorInfo();
			se.setErrorCode(ee.getBasheError().getErrorCode());
			se.setTrace(ee.getBasheError().getErrorTrace());
			errs.add(se);
		}
		d.setErrors(errs);

		return d;
	}

	public static String retry(String logId, String data)
			throws BifangException {
		SoaStatDetailLog log = StatDetailLogDao.getStatLogByMessageLog(logId);
		SoaHttpBinding hb = (SoaHttpBinding) BusBindingDao.getBusBinding(log
				.getBusCode(), EntityConstants.BUS_BINDING_RETRY,
				EntityConstants.BINDING_HTTP);

		RetryRequestDocument reqdoc = RetryRequestDocument.Factory
				.newInstance();
		reqdoc.addNewRetryRequest().setMessageLogId(logId);
		if (data != null) {
			System.out.println("data is [" + data + "]");
			XmlObject xo = null;
			
			try {
				
		         
		        
				xo = XmlObject.Factory.parse(data);
			} catch (Exception e) {
				throw new BifangException(
						BifangErrorCode.RETRY_DATA_FORMAT_ERROR,
						"retry xml format error");
			}

//			if (!xo.validate()) {
//				 for(int i = 0,j = errorList.size(); i < j ; i ++){
//		                XmlError err = (XmlError)errorList.get(i);
//		               System.out.println(err.getMessage());
//		               System.out.println(("Location of invalid XML: " +  err.getCursorLocation().xmlText())    );
//		                
//		            }  
//				throw new BifangException(
//						BifangErrorCode.RETRY_DATA_FORMAT_ERROR,
//						"retry xml format error");
//			}
			reqdoc.getRetryRequest().addNewRequest().set(xo);

		}
		RetryResponseDocument resdoc = BasheClient.retry(reqdoc, hb.getUrl(),
				60);
		return resdoc.getRetryResponse().getStatus();
	}

}
